package ar.edu.itba.ontologias.TPONTO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.sparql.vocabulary.FOAF;
import com.hp.hpl.jena.vocabulary.RDF;

public class Helper {

	// PARA VER EJEMPLOS DE COMO USAR JSOP ENTRAR A:
	// http://jsoup.org/cookbook/extracting-data/selector-syntax

	public static String getType(String url) {
		String ans;
		String urlPart = new String("http://www.cinenacional.com/");
		// System.out.println("Termino");

		if (url.indexOf(urlPart) != -1) {
			if (urlPart.length() < url.lastIndexOf("/"))
				ans = url.substring(urlPart.length(), url.lastIndexOf("/"));
			else
				ans = url.substring(urlPart.length(), url.length());
		} else
			ans = null;
		return ans;
	}

	public static Person getPerson(String contentType) {
		Document doc = Jsoup.parse(contentType);

		Elements metas = doc.select("meta");
		String[] aux = getTitleAndPath(metas);
		String title = aux[0];
		String path = aux[1];

		Element birth = doc.getElementById("persona-nacimiento");
		String birthDate = getDate(birth);

		Element death = doc.getElementById("persona-muerte");
		String deathDate = getDate(death);

		Element country = doc.getElementById("persona-nacionalidad");// <img
		// title="Argentina">
		String countryName = null;
		if (country != null)
			countryName = country.select("img").attr("title"); // devuelve
																// Argentina

		Element image = doc.getElementById("persona-foto"); // <img
		// src="http://www.cinenacional.com/sites/default/files/styles/220_w/public/none.jpg">
		String imageUrl = null;
		if (image != null)
			imageUrl = image.select("img").attr("src"); // devuelve url

		Elements role = doc.select("div.persona-filmografia-rol");
		Map<String, List<String>> past = getPastRoles(role);

		return new Person(path, title, birthDate, deathDate, countryName,
				imageUrl, past);
	}

	private static String[] getTitleAndPath(Elements metas) {

		String[] aux = { "", "" };
		if (metas != null) {
			for (Element e : metas) {
				if (e.attr("property").equalsIgnoreCase("dc:title")) {
					aux[0] = e.attr("content");
					String[] split = e.attr("about").split("/");
					aux[1] = split[2];
				}
			}
		}
		return aux;
	}

	private static String getDate(Element elem) {
		// devuelve <div class="field-label">Nacimiento:&nbsp;</div>
		// <a href="/efemerides/09/07">7 de septiembre</a> de 1961

		String date = null;
		int month = 0;
		int day = 0;
		int year = 0;

		if (elem != null) {

			String[] aux = elem.select("a").attr("href").split("/");

			if (aux != null) {
				month = Integer.parseInt(aux[2]);
				day = Integer.parseInt(aux[3]);
			}

			if (aux != null) {
				String temp = elem.html().substring(
						elem.html().lastIndexOf("</a> de ") + 8,
						elem.html().length());
				year = Integer.parseInt(temp);
			}

			date = year + "-" + (month < 10 ? "0" : "") + month + "-"
					+ (day < 10 ? "0" : "") + day;
		}
		return date;
	}

	private static Map<String, List<String>> getPastRoles(Elements elems) {
		Map<String, List<String>> past = null;

		if (elems != null) {
			past = new HashMap<String, List<String>>();
			for (Element e : elems) {
				String roleTitle = e.select("h4").text(); // <h4>Int√©rprete</h4>
				List<Element> movieElements = e.select("a"); // <a
				// href="/pelicula/miedo-satanico">
				// hay + de
				// una!
				List<String> movieURLs = new ArrayList<String>();
				for (Element el : movieElements) {
					String[] split = el.attr("href").split("/");
					movieURLs.add(split[2]);
				}
				past.put(roleTitle, movieURLs);
			}
		}
		return past;
	}

	public static Movie getMovie(String contentType) {
		Document doc = Jsoup.parse(contentType);

		Elements metas = doc.select("meta");
		String[] aux = getTitleAndPath(metas);
		String title = aux[0];
		String path = aux[1];

		Element country = doc.getElementById("pelicula-origen"); // <img
		// title="argentina"
		// hay + de
		// uno!
		List<String> countryNames = null;
		if (country != null) {
			List<Element> countryElements = country.select("img");
			countryNames = new ArrayList<String>();
			for (Element e : countryElements) {
				countryNames.add(e.attr("title"));
			}
		}

		Element cat = doc.getElementById("pelicula-tipo-duracion");
		String category = null;
		if (cat != null) {
			category = cat.text();
		}

		Element length = doc.getElementById("cine-pelicula-duracion"); // buscar
		// Duraci&oacute;n:&nbsp;</div>78&nbsp;minutos
		int lengthInt = 0;
		if (length != null) {
			aux = length.html().split("&nbsp;");
			lengthInt = Integer.parseInt(aux[1].substring(7));
		}

		Element release = doc.getElementById("pelicula-fecha-estreno");
		String releaseDate = getReleaseDate(release);

		Element titles = doc.getElementById("cine-pelicula-titulos"); // <div
		// class="pelicula-titulos-row>
		// hay +
		// de
		// uno!
		List<String> titleNames = null;
		if (titles != null) {
			Elements titleElements = titles.select("div.pelicula-titulos-row");
			titleNames = new ArrayList<String>();
			for (Element e : titleElements) {
				titleNames.add(e.text());
			}
		}

		Element image = doc.getElementById("pelicula-afiche");
		String imageUrl = null;
		if (image != null) {
			imageUrl = image.select("img").attr("src"); // devuelve url
		}

		return new Movie(path, title, countryNames, category, lengthInt,
				releaseDate, titleNames, imageUrl);
	}

	private static String getReleaseDate(Element elem) {
		// a
		// href="/efemerides/05/03"
		// y a
		// href="/estrenos/1951"
		String releaseDate = null;
		int year = 0;
		int month = 0;
		int date = 0;
		int i = 0;

		if (elem != null) {

			Elements releaseDatesElements = elem.select("a");
			List<String> releaseDates = new ArrayList<String>();
			for (Element e : releaseDatesElements) {
				releaseDates.add(e.attr("href"));
			}

			String[] aux = releaseDates.get(i).split("/");

			if (aux != null && aux[1].equalsIgnoreCase("efemerides")) {
				month = Integer.parseInt(aux[2]);
				date = Integer.parseInt(aux[3]);
				i++;
			}

			aux = releaseDates.get(i).split("/");

			if (aux != null && aux[1].equalsIgnoreCase("estrenos")) {
				year = Integer.parseInt(aux[2]);
			}

			releaseDate = year + "-" + (month < 10 ? "0" : "") + month + "-"
					+ (date < 10 ? "0" : "") + date;
		}
		return releaseDate;
	}

	private static Model mP = ModelFactory.createDefaultModel();
	private static Model mM = ModelFactory.createDefaultModel();

	public static void makeRDF(Person p) throws FileNotFoundException {
		OutputStream in = new FileOutputStream("persons.rdf");
		mP.setNsPrefix("person",nsPerson);
		mP.setNsPrefix("dbpedia",nsCountry);
		mP.setNsPrefix("foaf",FOAF.getURI());
		
		Resource r = mP.createResource(nsPerson + "#" + p.getPath());
		r.addProperty(RDF.type, FOAF.Person);

		if (p.getName() != null)
			r.addProperty(FOAF.name, p.getName());
		if (p.getBirthDate() != null)
			r.addProperty(birthDate, p.getBirthDate());
		if (p.getDeathDate() != null) {
			r.addProperty(deathDate, p.getDeathDate());
		}
		if (p.getCountry() != null)
			r.addProperty(countryP,
					mP.createResource(nsCountry + "#" + p.getCountry()));
		if (p.getImageUrl() != null
				&& !p.getImageUrl().equalsIgnoreCase(emptyUrl)) {
			r.addProperty(photo, mP.createResource(p.getImageUrl()));
		}

		if (p.getPast() != null) {
			if (p.getPast().size() > 0) {
				for (Entry<String, List<String>> entry : p.getPast().entrySet()) {
					entry.getKey();
					if (entry.getKey().equalsIgnoreCase("intérprete")) {
						for (String movie : entry.getValue())
							r.addProperty(actedOn,
									mP.createResource(nsMovie + "#" + movie));
					} else if (entry.getKey().equalsIgnoreCase("director")) {
						for (String movie : entry.getValue())
							r.addProperty(directedOn,
									mP.createResource(nsMovie + "#" + movie));
					} else if (entry.getKey().equalsIgnoreCase("guionista")) {
						for (String movie : entry.getValue())
							r.addProperty(wroteOn,
									mP.createResource(nsMovie + "#" + movie));
					} else if (entry.getKey().equalsIgnoreCase("producción")) {
						for (String movie : entry.getValue())
							r.addProperty(producedOn,
									mP.createResource(nsMovie + "#" + movie));
					} else if (entry.getKey().equalsIgnoreCase("sonido")) {
						for (String movie : entry.getValue())
							r.addProperty(playedOn,
									mP.createResource(nsMovie + "#" + movie));
					} else if (entry.getKey().equalsIgnoreCase("cámara")) {
						for (String movie : entry.getValue())
							r.addProperty(filmedOn,
									mP.createResource(nsMovie + "#" + movie));
					} else if (entry.getKey().equalsIgnoreCase("fotografía")) {
						for (String movie : entry.getValue())
							r.addProperty(photographedOn,
									mP.createResource(nsMovie + "#" + movie));
					}
				}
			}
		}

		mP.write(in);
		// System.exit(0);

	}

	private static String nsBase = "http://www.example.org/";
	private static String nsMovie = "http://www.example.org/Movie/";
	private static String nsPerson = "http://www.example.org/Person/";
	private static String nsCountry = "http://es.dbpedia.org/resource/";
	private static Property photo = mP.createProperty(nsPerson, "photo");
	private static Property poster = mM.createProperty(nsMovie, "poster");
	private static Property length = mM.createProperty(nsMovie, "length");
	private static Property category = mM.createProperty(nsMovie, "category");
	private static Property releaseDate = mM.createProperty(nsMovie,
			"releaseDate");
	private static Property alternativeTitle = mM.createProperty(nsMovie,
			"alternativeTitle");
	private static Property birthDate = mP
			.createProperty(nsPerson, "birthDate");
	private static Property deathDate = mP
			.createProperty(nsPerson, "deathDate");
	private static Resource movieResource = mM.createResource(nsMovie+"Movie");
	private static Property actedOn = mP.createProperty(nsPerson, "actedOn");
	private static Property directedOn = mP.createProperty(nsPerson,
			"directedOn");
	private static Property wroteOn = mP.createProperty(nsPerson, "wroteOn");
	private static Property producedOn = mP.createProperty(nsPerson,
			"producedOn");
	private static Property playedOn = mP.createProperty(nsPerson, "playedOn");
	private static Property filmedOn = mP.createProperty(nsPerson, "filmedOn");
	private static Property photographedOn = mP.createProperty(nsPerson,
			"photographedOn");
	private static Property countryP = mP.createProperty(nsCountry, "country");
	private static Property countryM = mM.createProperty(nsCountry, "country");
	private static String emptyUrl = "http://www.cinenacional.com/sites/default/files/styles/220_w/public/none.jpg";

	public static void makeRDF(Movie movie) throws FileNotFoundException {
		OutputStream in = new FileOutputStream("movies.rdf");
		mM.setNsPrefix("movie",nsMovie);
		mM.setNsPrefix("dbpedia",nsCountry);
		mM.setNsPrefix("foaf",FOAF.getURI());

		Resource r = mM.createResource(nsMovie + "#" + movie.getPath());
		r.addProperty(RDF.type, movieResource);
		if (movie.getTitle() != null)
			r.addProperty(FOAF.name, movie.getTitle());
		if (movie.getCountryNames() != null) {
			if (movie.getCountryNames().size() > 0) {
				for (String name : movie.getCountryNames()) {
					r.addProperty(countryM,
							mM.createResource(nsCountry + "#" + name));
				}
			}
		}
		if (movie.getLength() > 0) {
			r.addProperty(length, String.valueOf(movie.getLength()));
		}
		if (movie.getCategory() != null) {
			r.addProperty(
					category,
					mM.createResource(nsBase + "#"
							+ String.valueOf(movie.getCategory())));
		}
		if (movie.getReleaseDate() != null) {
			r.addProperty(releaseDate, movie.getReleaseDate());
		}
		if (movie.getAlternativeTitles() != null) {
			if (movie.getAlternativeTitles().size() > 0) {
				for (String name : movie.getAlternativeTitles())
					r.addProperty(alternativeTitle, name);
			}
		}

		if (movie.getImageUrl() != null
				&& !movie.getImageUrl().equalsIgnoreCase(emptyUrl)) {
			r.addProperty(poster, mM.createResource(movie.getImageUrl()));
		}

		mM.write(in);
		// System.exit(0);
	}

}
